﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;

namespace DO.DreamOnTrader.Quote
{
	/// <summary>
	/// 可取得歷史報價，來源可為期交所之歷史tick檔
	/// </summary>
	public abstract class TickFileLoader : TickLoader
	{
		/// <summary>
		/// 建構式
		/// </summary>
		/// <param name="_rptFolder">目錄路徑</param>
		public TickFileLoader(string _rptFolder, Product _product, int _addQuoteMonth = 0, int _filterMinute = 30)
		{
			rptFolder = _rptFolder;
			filterProduct = _product;
			addQuoteMonth = _addQuoteMonth;
			filterMinute = _filterMinute;
		}


		/// <summary>
		/// 取得或設定rpt檔案之路徑
		/// </summary>
		public string rptFolder { get; set; }
		
		/// <summary>
		/// 是否己載入tick
		/// </summary>
		private bool loadTickComplete = false;

		/// <summary>
		/// list存放己load的tick
		/// </summary>
		private List<Tick> ticks = new List<Tick>();

		/// <summary>
		/// 紀錄user是否有按下stop()
		/// </summary>
		private bool exec = true;

		/// <summary>
		/// 重載tick檔
		/// </summary>
		public void ReLoadingTick()
		{
			loadTickComplete = false;
			ticks.Clear();
		}

		/// <summary>
		/// 將rpt檔案轉成tick
		/// </summary>
		private void loadTick()
		{
			DO.Common.Trace.InfoWrite("loadTick", "載入tick檔案");
			string[] strFiles = Directory.GetFiles(rptFolder, "*.rpt");
			ticks.Clear();

			long lineCount = 0;

			Parallel.ForEach<string>(strFiles, (name, loopState) =>
			{
				using (StreamReader sr = new StreamReader(name, System.Text.Encoding.Default))
				{
					String tickline;
					tickline = sr.ReadLine();	//去除標頭
					while ((tickline = sr.ReadLine()) != null)
					{
						try
						{
							#region 處理tick檔
							string[] temp = tickline.Split(',');
							Product product = ProductSet.parse(temp[1].Trim());
							string CloseMonth = temp[2].Trim();
							float price = Convert.ToSingle(temp[4].Trim());
							uint qty = Convert.ToUInt32(temp[5].Trim()) / 2;
							DateTime TradeTime = new DateTime(Convert.ToInt32(temp[0].Substring(0, 4)), Convert.ToInt32(temp[0].Substring(4, 2)), Convert.ToInt32(temp[0].Substring(6, 2)),
									Convert.ToInt32(temp[3].Substring(0, 2)), Convert.ToInt32(temp[3].Substring(2, 2)), Convert.ToInt32(temp[3].Substring(4, 2)));
							#endregion

							Tick ti = new Tick(price, product, qty, TradeTime, CloseMonth, lineCount);

							if (base.checkProduct(ti) && base.checkCloseMonth(ti))
							{
								lock (ticks)
								{
									lineCount++;
									ticks.Add(ti);
								}
							}

						}
						catch (IndexOutOfRangeException ex)
						{
							DO.Common.Trace.ErrorWrite("loadTick", name + ",line=" + lineCount + "," + ex.Message + ",tickline=" + tickline);
						}

						if (exec == false) break;
					}
				}

				if (exec == false) loopState.Stop();
			});

			if (exec == true)
			{
				ticks.Sort();
				DO.Common.Trace.DebugWrite("loadTick", "count=" + ticks.Count.ToString());
				loadTickComplete = true;
			}
		}

		#region =====TickLoader 成員

		/// <summary>
		/// 開始Load Tick
		/// </summary>
		/// <returns></returns>
		public override bool  Start()
		{
			DO.Common.Trace.InfoWrite("Start", "TickLoader Start()");
			exec = true;
			if (loadTickComplete == false) loadTick();
			if (exec == true)
			{
				foreach (Tick ti in ticks)
				{
					proecessTick(ti);
					if (exec == false) break;
				}
				if (exec == true) toEndQuote();
			}
			return true;
		}

		/// <summary>
		/// 停止Load Tick
		/// </summary>
		/// <returns></returns>
		public override bool Stop()
		{
			exec = false;
			DO.Common.Trace.InfoWrite("loadTick", "使用者中止");
			return true;
		}

		#endregion

	}
}
